// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef LEMC_RESOURCE_MANAGER_H
#define LEMC_RESOURCE_MANAGER_H

#include <unordered_map>
#include <string>
#include <fstream>

#include "../util/logmanager.h"

/*
A resource manager for any type of data.
*/
template <class T>
class ResourceManager
{
protected:
	// The path to the file where the paths to the resources are stored.
	std::string m_resource_file_path;

	// The resources that have been loaded already.
	std::unordered_map<std::string, T> m_resources;
	
	/*
	* Looks for the resource of name 'resource_id' within the resource_file defined in m_resource_file_path.
	* If it is found there, the path to the requested resource is returned in the parameter path.
	*
	* @param resource_id The identifier of the resource.
	* @param path The string where the path to the resource is stored.
	* 
	* @return True if the resource was found in the resource file and the path could be obtained, false else.
	*/
	virtual bool GetResourcePathFromFile(std::string resource_id, std::string &path);

	/*
	* Loads a resource into the memory.
	*
	* @param resource_id The identifier of the resource.
	* 
	* @return True if the resource could be loaded, false else.
	*/
	virtual bool LoadResource(std::string resource_id) = 0;

	/*
	* Destroys a resource.
	*
	* @param resource The resource to be destroyed.
	* 
	* @return True if the resource could be destroyed, false else.
	*/
	virtual bool DestroyResource(T resource) = 0;

public:
	/*
	* The contructor initializes the class with the path to the file that contains the path to
	* every resource available.
	*
	* @param resource_file_path The path to the resource file.
	*/
	ResourceManager(std::string resource_file_path);

	/*
	* Destructor does nothing yet.
	* TODO: Why can't it free all resources?
	*/
	~ResourceManager();

	/*
	* Gets a resource. If it is not yet loaded, this method also schedules the loading of the resource.
	*
	* @param resource_id The identifier of the resource to be loaded.
	*
	* @return The resource.
	*/
	T GetResource(std::string resource_id);

	/*
	* Frees a resource in order to free up memory space.
	*
	* @param resource_id The identifier of the resource to be freed.
	*
	* @return True if the resource has been freed successfully, false if there were problems.
	*/
	bool FreeResource(std::string resource_id);

	/*
	* Frees all resource in order to free up memory space.
	*
	* @return True if the all resources have been freed successfully, false if there were problems.
	*/
	bool FreeAllResources();
};

#include "resource_manager.cpp"

#endif